package com.y.mytest.file;


import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.io.FileUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.util.Arrays;

/**
 * @ClassName: FileUtils
 * @author: 叶子豪
 * @create: 2021-05-18 14:55
 */
public class FileUtil {
    public static void main(String[] args) throws Exception {
        long startTime = System.currentTimeMillis();

        //splitFile(new File("D:/test/postman_zhbao.zip"), 10 * 1024 * 1024);
        System.out.println(DigestUtils.md5Hex("1"));
        byte[] b = new byte[]{1};
        System.out.println(DigestUtils.md5Hex(b));

        long endTime = System.currentTimeMillis();
        System.out.println("耗费时间： " + (endTime - startTime) + " ms");
    }

    public static void splitMultipartToMD5(MultipartFile binFile) throws IOException {
        File file = new File(binFile.getName());
        FileUtils.copyInputStreamToFile(binFile.getInputStream(), file);
        splitFile(file, 10 * 1024 * 1024);
    }//DigestUtils.md5Hex()  List<String>

    public static void splitMFile(MultipartFile file) throws IOException {
        byte[] bytes = file.getBytes();

        final int fileSize = Math.toIntExact(bytes.length);
        int bufferSize = 10 * 1024 * 1024;
        int fileCount = fileSize % bufferSize == 0 ? fileSize / bufferSize : fileSize / bufferSize + 1;
        int startPosition = 0; //子文件开始位置
        int endPosition = bufferSize;//子文件结束位置

        for (int i = 0; i < fileCount; i++) {
            byte[] copy = Arrays.copyOfRange(bytes, startPosition, endPosition);
            System.out.println(DigestUtils.md5Hex(copy));
            startPosition = endPosition + 1;
            endPosition += bufferSize;
        }

    }

    public static void splitFile(File file, int average) throws IOException {
        FileInputStream fis = new FileInputStream(file);
        FileChannel inputChannel = fis.getChannel();
        final int fileSize = Math.toIntExact(inputChannel.size());
        int fileCount = fileSize % average == 0 ? fileSize / average : fileSize / average + 1;

        long bufferSize = 10 * 1024 * 1024; //缓存块大小，自行调整
        ByteBuffer byteBuffer = ByteBuffer.allocate(Integer.parseInt(bufferSize + "")); // 申请一个缓存区
        long startPosition = 0; //子文件开始位置
        long endPosition = bufferSize;//average < bufferSize ? 0 : average - bufferSize + (bufferSize);//子文件结束位置
        for (int i = 0; i < fileCount; i++) {

            if (i + 1 != fileCount) {
                int read = inputChannel.read(byteBuffer, endPosition);// 读取数据

                readW:
                while (read != -1) {
                    byteBuffer.flip();//切换读模式
                    byte[] array = byteBuffer.array();

                    System.out.println(DigestUtils.md5Hex(array));

                    for (int j = 0; j < array.length; j++) {
                        byte b = array[j];
                        if (b == 10 || b == 13) { //判断\n\r
                            endPosition += j;
                            break readW;
                        }
                    }
                    endPosition += bufferSize;
                    byteBuffer.clear(); //重置缓存块指针
                    read = inputChannel.read(byteBuffer, endPosition);
                }
            } else {
                endPosition = fileSize; //最后一个文件直接指向文件末尾

                ByteBuffer endByte = ByteBuffer.allocate(Integer.parseInt(bufferSize + ""));
                inputChannel.read(endByte, endPosition);
                byte[] array = byteBuffer.array();
                System.out.println(DigestUtils.md5Hex(array));
            }
            /*FileOutputStream fos = new FileOutputStream(file.getPath() + (i + 1));
            FileChannel outputChannel = fos.getChannel();
            inputChannel.transferTo(startPosition, endPosition - startPosition, outputChannel);//通道传输文件数据
            outputChannel.close();
            fos.close();*/

            startPosition = endPosition + 1;
            endPosition += average;
        }
        inputChannel.close();
        fis.close();
    }

}
